SlideShare ist ein Scribd-Unternehmen logo
1 von 84
Vinai Kopp 
Manchester, November 1st 2014
Introduction 
Magento 1.x 
2 The beautiful Magento Module November, 1st 2014
Introduction 
Magento 1.x 
It has contributed to the collective knowledge 
of the PHP community. 
Both as a good and a bad example :) 
3 The beautiful Magento Module November, 1st 2014
Introduction 
This is not 
an introduction into 
Magento development. 
4 The beautiful Magento Module November, 1st 2014
Introduction 
How can 
a Magento module 
be "beautiful"? 
5 The beautiful Magento Module November, 1st 2014
Introduction 
Qualities of a beautiful module 
1.It provides business value 
2.Magento can be upgraded without breaking the module 
3.It is easy to understand and modify 
4.It has good test coverage 
5.It is free of bugs 
6 The beautiful Magento Module November, 1st 2014
Principles and Patterns 
7 The beautiful Magento Module November, 1st 2014
Principles and Patterns 
Robert C. Martin (Uncle Bob) 
8 The beautiful Magento Module November, 1st 2014
Principles and Patterns 
Some principles and some of their fancy acronyms 
•Single Responsibility Principle (SRP) 
•Open Closed Principle (OCP) 
•Liskov Substitution Principle (LSP) 
•Interface Segregation Principle (ISP) 
•Dependency Inversion Principle (DIP) 
9 The beautiful Magento Module November, 1st 2014
Principles and Patterns 
Some more principles and some more fancy acronyms 
•Encapsulate what varies (ECV) 
•Strive for loosely coupled designs between objects that interact (LC) 
•Favor composition over inheritance (FCoI) 
•Only talk to friends (LoD) 
•Don't call us, we'll call you (IoC) 
10 The beautiful Magento Module November, 1st 2014
Principles and Patterns 
What have you done for 
me lately, principles? 
11 The beautiful Magento Module November, 1st 2014
Principles and Patterns 
Like with all good 
things in life, 
there can be too much. 
12 The beautiful Magento Module November, 1st 2014
Open Closed Principle 
13 The beautiful Magento Module November, 1st 2014
“Classes should be open for extension but 
closed for modification” 
The Open Closed Principle 
Uncle Bob 
14 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
Does Magento have it? 
15 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
Configuration XML merging 
Often the cause of conflicts 
16 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
Lets look deeper 
17 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
Self-Documenting Code 
Method visibility and naming 
18 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
public Methods 
Are an open invitation to the world 
19 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
public Methods 
Once published should never change 
their signature or functionality 
20 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
protected Methods 
Communicate “override me!” 
21 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
protected Methods 
Change in signature or functionality 
risks breaking subclasses 
22 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
private Methods 
Safe to change 
23 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
How is method visibility used in 
Magento? 
Only public and protected 
A too open design! 
24 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
A good example of 
method visibility documenting 
how to extend a class. 
25 The beautiful Magento Module November, 1st 2014
A good example from the core how method visibility helps 
abstract class Mage_Core_Block_Abstract ... 
{ 
final public function toHtml() 
{ 
// ...housekeeping 
$html = $this->_toHtml(); 
// ...more housekeeping 
return $html; 
} 
protected function _toHtml() 
{ 
return ''; 
} 
26 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
Another good example of OCP 
Event Observers 
27 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
How can we apply this principle 
to our modules? 
By dispatching events 
28 The beautiful Magento Module November, 1st 2014
Choosing strategic places to dispatch events. 
Mage::dispatchEvent('events_example_import_prepare', ['importer' => $this]); 
// ... 
Mage::dispatchEvent( 
'events_example_import_batch_start', 
['importer' => $this, 'batch' => $batch] 
); 
// ... 
Mage::dispatchEvent( 
'events_example_import_batch_end', 
['importer' => $this, 'batch' => $batch]); 
// ... 
Mage::dispatchEvent('events_example_import_complete', ['importer' => $this]); 
29 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
Favor domain events over 
instructional events 
30 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
Choose the right method visibility 
Use private as the default 
31 The beautiful Magento Module November, 1st 2014
The Open Closed Principle 
Use the Magento Factory Methods 
and Class Aliases 
32 The beautiful Magento Module November, 1st 2014
Rewrites are applied during class name resolution. 
Using a Factory Method with a PHP class name 
is no better then using new. 
$notLikeThis = new Mage_Catalog_Model_Product(); 
$badExample = Mage::getModel('Mage_Catalog_Model_Product'); 
33 The beautiful Magento Module November, 1st 2014
Rewrites are applied during class name resolution. 
Using class aliases allows for rewrites. 
$correctlyInstantiated = Mage::getModel('catalog/product'); 
gist of class name resolution steps: 
http://vin.ai/class-name-resolution 
34 The beautiful Magento Module November, 1st 2014
To keep our code open for extension, 
we should use class aliases for our classes. 
$model = Mage::getModel('example_module/import_parser_xml'); 
$resource = Mage::getResourceModel('example_module/search'); 
$helper = Mage::helper('example_module'); 
$block = Mage::app()->getLayout()->createBlock('example_module/list'); 
35 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
36 The beautiful Magento Module November, 1st 2014
“Encapsulate the Concept that Varies, i.e. a 
design is better when those parts that vary 
are encapsulated in a separate module” 
On the Criteria To Be Used in 
Decomposing Systems into Modules 
David Parnas 
37 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
Keep changes local so they don't 
affect other parts of the system 
38 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
Magento, do you ECV? 
39 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
First some "missed opportunities" 
40 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
Configuration of the 
Tax Calculation Algorithm 
41 The beautiful Magento Module November, 1st 2014
Choosing the tax calculation algorithm based on the system 
configuration 
// from Mage_Tax_Model_Sales_Quote_Tax::collect() 
switch ($this->_config->getAlgorithm($this->_store)) { 
case Mage_Tax_Model_Calculation::CALC_UNIT_BASE: 
$this->_unitBaseCalculation($address, $request); 
break; 
case Mage_Tax_Model_Calculation::CALC_ROW_BASE: 
$this->_rowBaseCalculation($address, $request); 
break; 
case Mage_Tax_Model_Calculation::CALC_TOTAL_BASE: 
$this->_totalBaseCalculation($address, $request); 
break; 
default: 
break; 
} 
42 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
Order State Management 
43 The beautiful Magento Module November, 1st 2014
Example of sales/order state behavior management 
public function canCancel() 
{ 
if (!$this->_canVoidOrder()) { 
return false; 
} 
if ($this->canUnhold()) { // $this->isPaymentReview() 
return false; 
} 
// ... more of the same + comments removed for brevity... 
$state = $this->getState(); 
if ($this->isCanceled() || $state === self::STATE_COMPLETE || 
$state === self::STATE_CLOSED) { 
return false; 
} 
if ($this->getActionFlag(self::ACTION_FLAG_CANCEL) === false) { 
return false; 
} 
return true; 
} 
44 The beautiful Magento Module November, 1st 2014
Theoretical example of encapsulating the stateful behavior 
class Mage_Sales_Model_Order_State_Complete implements OrderState 
{ 
public function canInvoice() 
{ 
return false; 
} 
public function canShip() 
{ 
return false; 
} 
public function canReorder() 
{ 
return true; 
} 
// ... 
45 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
Where does the core adhere to the 
principle, at least in parts? 
46 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
Total Models 
Total calculation 
Preparation of display data 
47 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
EAV Attribute Models 
Backend, 
Source and 
Frontend models 
48 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
How can we apply this principle 
in our Modules? 
49 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
A simple example scenario 
Add information 
depending on a the attribute set 
to the product detail page. 
50 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
A simple example scenario 
Kitchen Attribute Set 
Chair Attribute Set 
Insurance Attribute Set 
51 The beautiful Magento Module November, 1st 2014
First try, not adhering to the principle 
private function getTemplateForAttributeSet() 
{ 
switch ($this->getAttributeSetId()) { 
case $this->kitchenAttributeSetId: 
return 'example/attributesetinfo/kitchen-info.phtml'; 
case $this->chairAttributeSetId: 
return 'example/attributesetinfo/chair-info.phtml'; 
case $this->insuranceAttributeSetId: 
return 'example/attributesetinfo/insurance-info.phtml'; 
} 
} 
52 The beautiful Magento Module November, 1st 2014
The block also needs to provide all the methods 
called from the templates 
private function getTemplateForAttributeSet() 
{ 
switch ($this->getAttributeSetId()) { 
case $this->kitchenAttributeSetId: 
return 'example/attributesetinfo/kitchen-info.phtml'; 
case $this->chairAttributeSetId: 
return 'example/attributesetinfo/chair-info.phtml'; 
case $this->insuranceAttributeSetId: 
return 'example/attributesetinfo/insurance-info.phtml'; 
} 
} 
public function getChairCoverWashingInstructionsPDFUrl() {...} 
public function getInsuranceTermsAndConditions() {...} 
public function getKitchenDesignPdfUrl() {...} 
public function getServicePartnerDirectoryUrl() {...} 
53 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
Decomposed classes 
Kitchen Attribute Set Info Block 
Chair Attribute Set Info Block 
Insurance Attribute Set Info Block 
Attribute Set Info Block Locator 
54 The beautiful Magento Module November, 1st 2014
The locator extends core/text_list 
class Example_AttributeSetInfo_Block_InfoBlockLocator 
extends Mage_Core_Block_Text_List 
{ 
// ... 
} 
55 The beautiful Magento Module November, 1st 2014
Select and instantiate the delegate object 
protected function _prepareLayout() 
{ 
$infoBlockAlias = $this->_getInfoBlockClassAlias(); 
if (null !== $infoBlockAlias) { 
$this->insert($this->_createChildBlock($infoBlockAlias)); 
} 
} 
private function _getInfoBlockClassAlias() 
{ 
switch ($this->getAttributeSetId()) { 
case $this->kitchenAttributeSetId: 
return 'example_attributesetinfo/info_kitchen'; 
case $this->chairAttributeSetId: 
return 'example_attributesetinfo/info_chair'; 
case $this->insuranceAttributeSetId: 
return 'example_attributesetinfo/info_insurance'; 
} 
} 
56 The beautiful Magento Module November, 1st 2014
The attribute set dependent differences are encapsulated 
class Example_AttributeSetInfo_Block_Info_Chair 
extends Mage_Core_Block_Template 
{ 
protected function _prepareLayout() 
{ 
$this->setTemplate('example/attributesetinfo/chair-info.phtml'); 
} 
public function getChairCoverWashingInstructionsPDFUrl() 
{ 
return 'the url of the chair cover washing instructions pdf'; 
} 
} 
57 The beautiful Magento Module November, 1st 2014
Encapsulate what varies 
What would be affected by change? 
What would be affected by adding an attribute set? 
What would be affected if the output for one attribute set 
needs to change? 
58 The beautiful Magento Module November, 1st 2014
More Principles 
59 The beautiful Magento Module November, 1st 2014
What else makes a 
module beautiful? 
60 The beautiful Magento Module November, 1st 2014
Readable Code 
61 The beautiful Magento Module November, 1st 2014
Readable Code 
What makes code readable? 
Coding Standard 
62 The beautiful Magento Module November, 1st 2014
Obviously 
private function getInfoBlockClassAliasBadExample () { 
if ($this->getAttributeSetId()==$this->kitchenAttributeSetId) 
return 'example_attributesetinfo/info_kitchen'; 
if($this->chairAttributeSetId == $this->getAttributeSetId()) return 
'example_attributesetinfo/info_chair'; 
else 
// insurance attribute set 
return 'example_attributesetinfo/info_insurance'; 
} 
private function getInfoBlockClassAliasGoodExample() 
{ 
switch ($this->getAttributeSetId()) { 
case $this->kitchenAttributeSetId: 
return 'example_attributesetinfo/info_kitchen'; 
case $this->chairAttributeSetId: 
return 'example_attributesetinfo/info_chair'; 
case $this->insuranceAttributeSetId: 
return 'example_attributesetinfo/info_insurance'; 
} 
} 
63 The beautiful Magento Module November, 1st 2014
Readable Code 
What else makes code readable? 
Descriptive method names 
64 The beautiful Magento Module November, 1st 2014
Readable Code 
How can we choose good method 
names? 
A method should do only one thing. 
The name should state that thing. 
65 The beautiful Magento Module November, 1st 2014
Readable Code 
If naming a method is hard split it 
into smaller ones. 
66 The beautiful Magento Module November, 1st 2014
Readable Code 
First some examples of method 
names that could be improved 
67 The beautiful Magento Module November, 1st 2014
One bad example straight out of the Magento ORM 
protected function _construct() 
{ 
$this->_init('example_module/foo'); 
} 
68 The beautiful Magento Module November, 1st 2014
I find this would be nicer to read 
protected function _initializeCollection() 
{ 
$this->_setModelClassAlias('example_module/foo'); 
} 
69 The beautiful Magento Module November, 1st 2014
Readable Code 
Methods returning a boolean value should start with is or has 
public function isNewObject() {...} 
public function hasChildren() {...} 
70 The beautiful Magento Module November, 1st 2014
Readable Code 
Setters should start with set 
$request->setDispatched(false) 
71 The beautiful Magento Module November, 1st 2014
Readable Code 
Some more good bad examples 
72 The beautiful Magento Module November, 1st 2014
Similar methods need very descriptive names to be self documenting 
// from Mage_Catalog_Model_Category 
public function getChildrenCategories() {...} 
public function getChildrenCategoriesWithInactive() {...} 
public function getChildren() {...} 
public function getAllChildren(...) {...} 
public function getCategories(...) {...} 
73 The beautiful Magento Module November, 1st 2014
Dead code should be removed without mercy 
// from Mage_Core_Model_Email 
public function __construct() 
{ 
// TODO: move to config 
$this->setFromName('Magento'); 
$this->setFromEmail('magento@varien.com'); 
$this->setType('text'); 
} 
74 The beautiful Magento Module November, 1st 2014
WTF 
// from Mage_Shipping_Model_Carrier_Abstract 
public function getTotalNumOfBoxes($weight) 
{ 
// ... 
return $weight; 
} 
75 The beautiful Magento Module November, 1st 2014
Wrap up 
76 The beautiful Magento Module November, 1st 2014
Wrap up 
What qualifies a Magento module as beautiful? 
1.It provides business value 
2.Magento can be upgraded without breaking the module 
3.It is easy to understand and modify 
4.It has good test coverage 
5.It is free of bugs 
77 The beautiful Magento Module November, 1st 2014
Further reading 
78 The beautiful Magento Module November, 1st 2014
Further reading 
Link to Amazon 
79 The beautiful Magento Module November, 1st 2014
Further reading 
Link to Amazon 
80 The beautiful Magento Module November, 1st 2014
Further reading 
Link to Amazon 
81 The beautiful Magento Module November, 1st 2014
Further reading 
Link to Amazon 
82 The beautiful Magento Module November, 1st 2014
Thank you 
83 The beautiful Magento Module November, 1st 2014
Questions | Comments 
Tweet me @VinaiKopp 
http://vinaikopp.com 
84 The beautiful Magento Module November, 1st 2014

Weitere ähnliche Inhalte

Ähnlich wie The beautiful Magento module - MageTitans 2014

Tsvetan stoychev m_mspeakers-edited-final
Tsvetan stoychev m_mspeakers-edited-finalTsvetan stoychev m_mspeakers-edited-final
Tsvetan stoychev m_mspeakers-edited-finalceckoslab
 
Refactoring Tips by Martin Fowler
Refactoring Tips by Martin FowlerRefactoring Tips by Martin Fowler
Refactoring Tips by Martin FowlerIgor Crvenov
 
Introduction to Using PHP & MVC Frameworks
Introduction to Using PHP & MVC FrameworksIntroduction to Using PHP & MVC Frameworks
Introduction to Using PHP & MVC FrameworksGerald Krishnan
 
PrestaShop Kathmandu Ecommerce Meetup #2
PrestaShop Kathmandu Ecommerce Meetup #2PrestaShop Kathmandu Ecommerce Meetup #2
PrestaShop Kathmandu Ecommerce Meetup #2Hem Pokhrel
 
How, When, and Why to Patch a Module
How, When, and Why to Patch a Module How, When, and Why to Patch a Module
How, When, and Why to Patch a Module Phase2
 
Refactoring: Improving the design of existing code
Refactoring: Improving the design of existing codeRefactoring: Improving the design of existing code
Refactoring: Improving the design of existing codeKnoldus Inc.
 
Architecture and Analytical Study of Magento
Architecture and Analytical Study of MagentoArchitecture and Analytical Study of Magento
Architecture and Analytical Study of MagentoIRJET Journal
 
Implementing the Adapter Design Pattern
Implementing the Adapter Design PatternImplementing the Adapter Design Pattern
Implementing the Adapter Design PatternProdigyView
 
A Successful Magento Project From Design to Deployment
A Successful Magento Project From Design to DeploymentA Successful Magento Project From Design to Deployment
A Successful Magento Project From Design to DeploymentJoshua Warren
 
Introduction to Integration Tests in Magento / Adobe Commerce
Introduction to Integration Tests in Magento / Adobe CommerceIntroduction to Integration Tests in Magento / Adobe Commerce
Introduction to Integration Tests in Magento / Adobe CommerceBartosz Górski
 
Introduction to Integration Tests in Magento / Adobe Commerce
Introduction to Integration Tests in Magento / Adobe CommerceIntroduction to Integration Tests in Magento / Adobe Commerce
Introduction to Integration Tests in Magento / Adobe CommerceBartosz Górski
 
Drupal Camp Mumbai -Making Drupal Agile !
Drupal Camp Mumbai -Making Drupal Agile !Drupal Camp Mumbai -Making Drupal Agile !
Drupal Camp Mumbai -Making Drupal Agile !Renzil Dsilva
 
Get Started with Zend Framework 2
Get Started with Zend Framework 2Get Started with Zend Framework 2
Get Started with Zend Framework 2Mindfire Solutions
 
Natural course of refactoring - Mix-IT Lyon 2014
Natural course of refactoring - Mix-IT Lyon 2014Natural course of refactoring - Mix-IT Lyon 2014
Natural course of refactoring - Mix-IT Lyon 2014BNS IT
 
Simplifi commerce oracle atg commerce & endeca training
Simplifi commerce   oracle atg commerce & endeca trainingSimplifi commerce   oracle atg commerce & endeca training
Simplifi commerce oracle atg commerce & endeca trainingLokesh Kumar
 
Simplifi commerce oracle atg commerce & endeca training - n
Simplifi commerce   oracle atg commerce & endeca training - nSimplifi commerce   oracle atg commerce & endeca training - n
Simplifi commerce oracle atg commerce & endeca training - nLokesh Kumar
 
SimplifiCommerce - Oracle ATG Commerce & Endeca Training - N
SimplifiCommerce - Oracle ATG Commerce & Endeca Training - NSimplifiCommerce - Oracle ATG Commerce & Endeca Training - N
SimplifiCommerce - Oracle ATG Commerce & Endeca Training - NLokesh Kumar
 
Generic Repository Pattern in MVC3 Application with Entity Framework
Generic Repository Pattern in MVC3 Application with Entity FrameworkGeneric Repository Pattern in MVC3 Application with Entity Framework
Generic Repository Pattern in MVC3 Application with Entity FrameworkAkhil Mittal
 

Ähnlich wie The beautiful Magento module - MageTitans 2014 (20)

Tsvetan stoychev m_mspeakers-edited-final
Tsvetan stoychev m_mspeakers-edited-finalTsvetan stoychev m_mspeakers-edited-final
Tsvetan stoychev m_mspeakers-edited-final
 
Refactoring Tips by Martin Fowler
Refactoring Tips by Martin FowlerRefactoring Tips by Martin Fowler
Refactoring Tips by Martin Fowler
 
Introduction to Using PHP & MVC Frameworks
Introduction to Using PHP & MVC FrameworksIntroduction to Using PHP & MVC Frameworks
Introduction to Using PHP & MVC Frameworks
 
PrestaShop Kathmandu Ecommerce Meetup #2
PrestaShop Kathmandu Ecommerce Meetup #2PrestaShop Kathmandu Ecommerce Meetup #2
PrestaShop Kathmandu Ecommerce Meetup #2
 
How, When, and Why to Patch a Module
How, When, and Why to Patch a Module How, When, and Why to Patch a Module
How, When, and Why to Patch a Module
 
Refactoring: Improving the design of existing code
Refactoring: Improving the design of existing codeRefactoring: Improving the design of existing code
Refactoring: Improving the design of existing code
 
Architecture and Analytical Study of Magento
Architecture and Analytical Study of MagentoArchitecture and Analytical Study of Magento
Architecture and Analytical Study of Magento
 
Implementing the Adapter Design Pattern
Implementing the Adapter Design PatternImplementing the Adapter Design Pattern
Implementing the Adapter Design Pattern
 
Patterns In-Javascript
Patterns In-JavascriptPatterns In-Javascript
Patterns In-Javascript
 
Certification study-guide-mcd-v1 2
Certification study-guide-mcd-v1 2Certification study-guide-mcd-v1 2
Certification study-guide-mcd-v1 2
 
A Successful Magento Project From Design to Deployment
A Successful Magento Project From Design to DeploymentA Successful Magento Project From Design to Deployment
A Successful Magento Project From Design to Deployment
 
Introduction to Integration Tests in Magento / Adobe Commerce
Introduction to Integration Tests in Magento / Adobe CommerceIntroduction to Integration Tests in Magento / Adobe Commerce
Introduction to Integration Tests in Magento / Adobe Commerce
 
Introduction to Integration Tests in Magento / Adobe Commerce
Introduction to Integration Tests in Magento / Adobe CommerceIntroduction to Integration Tests in Magento / Adobe Commerce
Introduction to Integration Tests in Magento / Adobe Commerce
 
Drupal Camp Mumbai -Making Drupal Agile !
Drupal Camp Mumbai -Making Drupal Agile !Drupal Camp Mumbai -Making Drupal Agile !
Drupal Camp Mumbai -Making Drupal Agile !
 
Get Started with Zend Framework 2
Get Started with Zend Framework 2Get Started with Zend Framework 2
Get Started with Zend Framework 2
 
Natural course of refactoring - Mix-IT Lyon 2014
Natural course of refactoring - Mix-IT Lyon 2014Natural course of refactoring - Mix-IT Lyon 2014
Natural course of refactoring - Mix-IT Lyon 2014
 
Simplifi commerce oracle atg commerce & endeca training
Simplifi commerce   oracle atg commerce & endeca trainingSimplifi commerce   oracle atg commerce & endeca training
Simplifi commerce oracle atg commerce & endeca training
 
Simplifi commerce oracle atg commerce & endeca training - n
Simplifi commerce   oracle atg commerce & endeca training - nSimplifi commerce   oracle atg commerce & endeca training - n
Simplifi commerce oracle atg commerce & endeca training - n
 
SimplifiCommerce - Oracle ATG Commerce & Endeca Training - N
SimplifiCommerce - Oracle ATG Commerce & Endeca Training - NSimplifiCommerce - Oracle ATG Commerce & Endeca Training - N
SimplifiCommerce - Oracle ATG Commerce & Endeca Training - N
 
Generic Repository Pattern in MVC3 Application with Entity Framework
Generic Repository Pattern in MVC3 Application with Entity FrameworkGeneric Repository Pattern in MVC3 Application with Entity Framework
Generic Repository Pattern in MVC3 Application with Entity Framework
 

Mehr von vinaikopp

Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023vinaikopp
 
Hyvä from a developer perspective
Hyvä from a developer perspectiveHyvä from a developer perspective
Hyvä from a developer perspectivevinaikopp
 
Property Based Testing in PHP
Property Based Testing in PHPProperty Based Testing in PHP
Property Based Testing in PHPvinaikopp
 
Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019vinaikopp
 
Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018vinaikopp
 
SOS UiComponents
SOS UiComponentsSOS UiComponents
SOS UiComponentsvinaikopp
 
ClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRNClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRNvinaikopp
 
Magento 2 TDD Code Kata
Magento 2 TDD Code KataMagento 2 TDD Code Kata
Magento 2 TDD Code Katavinaikopp
 
Magento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata IntroMagento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata Introvinaikopp
 
Testing Magento 2
Testing Magento 2Testing Magento 2
Testing Magento 2vinaikopp
 
ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017vinaikopp
 
Lizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17deLizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17devinaikopp
 
Stories from the other side
Stories from the other sideStories from the other side
Stories from the other sidevinaikopp
 
Writing Testable Code (for Magento 1 and 2) 2016 Romaina
Writing Testable Code (for Magento 1 and 2)  2016 RomainaWriting Testable Code (for Magento 1 and 2)  2016 Romaina
Writing Testable Code (for Magento 1 and 2) 2016 Romainavinaikopp
 
Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)vinaikopp
 
Writing testable Code (MageTitans Mini 2016)
Writing testable Code (MageTitans Mini 2016)Writing testable Code (MageTitans Mini 2016)
Writing testable Code (MageTitans Mini 2016)vinaikopp
 
Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)vinaikopp
 
Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)vinaikopp
 

Mehr von vinaikopp (18)

Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023
 
Hyvä from a developer perspective
Hyvä from a developer perspectiveHyvä from a developer perspective
Hyvä from a developer perspective
 
Property Based Testing in PHP
Property Based Testing in PHPProperty Based Testing in PHP
Property Based Testing in PHP
 
Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019
 
Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018
 
SOS UiComponents
SOS UiComponentsSOS UiComponents
SOS UiComponents
 
ClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRNClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRN
 
Magento 2 TDD Code Kata
Magento 2 TDD Code KataMagento 2 TDD Code Kata
Magento 2 TDD Code Kata
 
Magento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata IntroMagento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata Intro
 
Testing Magento 2
Testing Magento 2Testing Magento 2
Testing Magento 2
 
ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017
 
Lizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17deLizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17de
 
Stories from the other side
Stories from the other sideStories from the other side
Stories from the other side
 
Writing Testable Code (for Magento 1 and 2) 2016 Romaina
Writing Testable Code (for Magento 1 and 2)  2016 RomainaWriting Testable Code (for Magento 1 and 2)  2016 Romaina
Writing Testable Code (for Magento 1 and 2) 2016 Romaina
 
Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)
 
Writing testable Code (MageTitans Mini 2016)
Writing testable Code (MageTitans Mini 2016)Writing testable Code (MageTitans Mini 2016)
Writing testable Code (MageTitans Mini 2016)
 
Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)
 
Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)
 

Kürzlich hochgeladen

Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 

Kürzlich hochgeladen (20)

Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 

The beautiful Magento module - MageTitans 2014

  • 1. Vinai Kopp Manchester, November 1st 2014
  • 2. Introduction Magento 1.x 2 The beautiful Magento Module November, 1st 2014
  • 3. Introduction Magento 1.x It has contributed to the collective knowledge of the PHP community. Both as a good and a bad example :) 3 The beautiful Magento Module November, 1st 2014
  • 4. Introduction This is not an introduction into Magento development. 4 The beautiful Magento Module November, 1st 2014
  • 5. Introduction How can a Magento module be "beautiful"? 5 The beautiful Magento Module November, 1st 2014
  • 6. Introduction Qualities of a beautiful module 1.It provides business value 2.Magento can be upgraded without breaking the module 3.It is easy to understand and modify 4.It has good test coverage 5.It is free of bugs 6 The beautiful Magento Module November, 1st 2014
  • 7. Principles and Patterns 7 The beautiful Magento Module November, 1st 2014
  • 8. Principles and Patterns Robert C. Martin (Uncle Bob) 8 The beautiful Magento Module November, 1st 2014
  • 9. Principles and Patterns Some principles and some of their fancy acronyms •Single Responsibility Principle (SRP) •Open Closed Principle (OCP) •Liskov Substitution Principle (LSP) •Interface Segregation Principle (ISP) •Dependency Inversion Principle (DIP) 9 The beautiful Magento Module November, 1st 2014
  • 10. Principles and Patterns Some more principles and some more fancy acronyms •Encapsulate what varies (ECV) •Strive for loosely coupled designs between objects that interact (LC) •Favor composition over inheritance (FCoI) •Only talk to friends (LoD) •Don't call us, we'll call you (IoC) 10 The beautiful Magento Module November, 1st 2014
  • 11. Principles and Patterns What have you done for me lately, principles? 11 The beautiful Magento Module November, 1st 2014
  • 12. Principles and Patterns Like with all good things in life, there can be too much. 12 The beautiful Magento Module November, 1st 2014
  • 13. Open Closed Principle 13 The beautiful Magento Module November, 1st 2014
  • 14. “Classes should be open for extension but closed for modification” The Open Closed Principle Uncle Bob 14 The beautiful Magento Module November, 1st 2014
  • 15. The Open Closed Principle Does Magento have it? 15 The beautiful Magento Module November, 1st 2014
  • 16. The Open Closed Principle Configuration XML merging Often the cause of conflicts 16 The beautiful Magento Module November, 1st 2014
  • 17. The Open Closed Principle Lets look deeper 17 The beautiful Magento Module November, 1st 2014
  • 18. The Open Closed Principle Self-Documenting Code Method visibility and naming 18 The beautiful Magento Module November, 1st 2014
  • 19. The Open Closed Principle public Methods Are an open invitation to the world 19 The beautiful Magento Module November, 1st 2014
  • 20. The Open Closed Principle public Methods Once published should never change their signature or functionality 20 The beautiful Magento Module November, 1st 2014
  • 21. The Open Closed Principle protected Methods Communicate “override me!” 21 The beautiful Magento Module November, 1st 2014
  • 22. The Open Closed Principle protected Methods Change in signature or functionality risks breaking subclasses 22 The beautiful Magento Module November, 1st 2014
  • 23. The Open Closed Principle private Methods Safe to change 23 The beautiful Magento Module November, 1st 2014
  • 24. The Open Closed Principle How is method visibility used in Magento? Only public and protected A too open design! 24 The beautiful Magento Module November, 1st 2014
  • 25. The Open Closed Principle A good example of method visibility documenting how to extend a class. 25 The beautiful Magento Module November, 1st 2014
  • 26. A good example from the core how method visibility helps abstract class Mage_Core_Block_Abstract ... { final public function toHtml() { // ...housekeeping $html = $this->_toHtml(); // ...more housekeeping return $html; } protected function _toHtml() { return ''; } 26 The beautiful Magento Module November, 1st 2014
  • 27. The Open Closed Principle Another good example of OCP Event Observers 27 The beautiful Magento Module November, 1st 2014
  • 28. The Open Closed Principle How can we apply this principle to our modules? By dispatching events 28 The beautiful Magento Module November, 1st 2014
  • 29. Choosing strategic places to dispatch events. Mage::dispatchEvent('events_example_import_prepare', ['importer' => $this]); // ... Mage::dispatchEvent( 'events_example_import_batch_start', ['importer' => $this, 'batch' => $batch] ); // ... Mage::dispatchEvent( 'events_example_import_batch_end', ['importer' => $this, 'batch' => $batch]); // ... Mage::dispatchEvent('events_example_import_complete', ['importer' => $this]); 29 The beautiful Magento Module November, 1st 2014
  • 30. The Open Closed Principle Favor domain events over instructional events 30 The beautiful Magento Module November, 1st 2014
  • 31. The Open Closed Principle Choose the right method visibility Use private as the default 31 The beautiful Magento Module November, 1st 2014
  • 32. The Open Closed Principle Use the Magento Factory Methods and Class Aliases 32 The beautiful Magento Module November, 1st 2014
  • 33. Rewrites are applied during class name resolution. Using a Factory Method with a PHP class name is no better then using new. $notLikeThis = new Mage_Catalog_Model_Product(); $badExample = Mage::getModel('Mage_Catalog_Model_Product'); 33 The beautiful Magento Module November, 1st 2014
  • 34. Rewrites are applied during class name resolution. Using class aliases allows for rewrites. $correctlyInstantiated = Mage::getModel('catalog/product'); gist of class name resolution steps: http://vin.ai/class-name-resolution 34 The beautiful Magento Module November, 1st 2014
  • 35. To keep our code open for extension, we should use class aliases for our classes. $model = Mage::getModel('example_module/import_parser_xml'); $resource = Mage::getResourceModel('example_module/search'); $helper = Mage::helper('example_module'); $block = Mage::app()->getLayout()->createBlock('example_module/list'); 35 The beautiful Magento Module November, 1st 2014
  • 36. Encapsulate what varies 36 The beautiful Magento Module November, 1st 2014
  • 37. “Encapsulate the Concept that Varies, i.e. a design is better when those parts that vary are encapsulated in a separate module” On the Criteria To Be Used in Decomposing Systems into Modules David Parnas 37 The beautiful Magento Module November, 1st 2014
  • 38. Encapsulate what varies Keep changes local so they don't affect other parts of the system 38 The beautiful Magento Module November, 1st 2014
  • 39. Encapsulate what varies Magento, do you ECV? 39 The beautiful Magento Module November, 1st 2014
  • 40. Encapsulate what varies First some "missed opportunities" 40 The beautiful Magento Module November, 1st 2014
  • 41. Encapsulate what varies Configuration of the Tax Calculation Algorithm 41 The beautiful Magento Module November, 1st 2014
  • 42. Choosing the tax calculation algorithm based on the system configuration // from Mage_Tax_Model_Sales_Quote_Tax::collect() switch ($this->_config->getAlgorithm($this->_store)) { case Mage_Tax_Model_Calculation::CALC_UNIT_BASE: $this->_unitBaseCalculation($address, $request); break; case Mage_Tax_Model_Calculation::CALC_ROW_BASE: $this->_rowBaseCalculation($address, $request); break; case Mage_Tax_Model_Calculation::CALC_TOTAL_BASE: $this->_totalBaseCalculation($address, $request); break; default: break; } 42 The beautiful Magento Module November, 1st 2014
  • 43. Encapsulate what varies Order State Management 43 The beautiful Magento Module November, 1st 2014
  • 44. Example of sales/order state behavior management public function canCancel() { if (!$this->_canVoidOrder()) { return false; } if ($this->canUnhold()) { // $this->isPaymentReview() return false; } // ... more of the same + comments removed for brevity... $state = $this->getState(); if ($this->isCanceled() || $state === self::STATE_COMPLETE || $state === self::STATE_CLOSED) { return false; } if ($this->getActionFlag(self::ACTION_FLAG_CANCEL) === false) { return false; } return true; } 44 The beautiful Magento Module November, 1st 2014
  • 45. Theoretical example of encapsulating the stateful behavior class Mage_Sales_Model_Order_State_Complete implements OrderState { public function canInvoice() { return false; } public function canShip() { return false; } public function canReorder() { return true; } // ... 45 The beautiful Magento Module November, 1st 2014
  • 46. Encapsulate what varies Where does the core adhere to the principle, at least in parts? 46 The beautiful Magento Module November, 1st 2014
  • 47. Encapsulate what varies Total Models Total calculation Preparation of display data 47 The beautiful Magento Module November, 1st 2014
  • 48. Encapsulate what varies EAV Attribute Models Backend, Source and Frontend models 48 The beautiful Magento Module November, 1st 2014
  • 49. Encapsulate what varies How can we apply this principle in our Modules? 49 The beautiful Magento Module November, 1st 2014
  • 50. Encapsulate what varies A simple example scenario Add information depending on a the attribute set to the product detail page. 50 The beautiful Magento Module November, 1st 2014
  • 51. Encapsulate what varies A simple example scenario Kitchen Attribute Set Chair Attribute Set Insurance Attribute Set 51 The beautiful Magento Module November, 1st 2014
  • 52. First try, not adhering to the principle private function getTemplateForAttributeSet() { switch ($this->getAttributeSetId()) { case $this->kitchenAttributeSetId: return 'example/attributesetinfo/kitchen-info.phtml'; case $this->chairAttributeSetId: return 'example/attributesetinfo/chair-info.phtml'; case $this->insuranceAttributeSetId: return 'example/attributesetinfo/insurance-info.phtml'; } } 52 The beautiful Magento Module November, 1st 2014
  • 53. The block also needs to provide all the methods called from the templates private function getTemplateForAttributeSet() { switch ($this->getAttributeSetId()) { case $this->kitchenAttributeSetId: return 'example/attributesetinfo/kitchen-info.phtml'; case $this->chairAttributeSetId: return 'example/attributesetinfo/chair-info.phtml'; case $this->insuranceAttributeSetId: return 'example/attributesetinfo/insurance-info.phtml'; } } public function getChairCoverWashingInstructionsPDFUrl() {...} public function getInsuranceTermsAndConditions() {...} public function getKitchenDesignPdfUrl() {...} public function getServicePartnerDirectoryUrl() {...} 53 The beautiful Magento Module November, 1st 2014
  • 54. Encapsulate what varies Decomposed classes Kitchen Attribute Set Info Block Chair Attribute Set Info Block Insurance Attribute Set Info Block Attribute Set Info Block Locator 54 The beautiful Magento Module November, 1st 2014
  • 55. The locator extends core/text_list class Example_AttributeSetInfo_Block_InfoBlockLocator extends Mage_Core_Block_Text_List { // ... } 55 The beautiful Magento Module November, 1st 2014
  • 56. Select and instantiate the delegate object protected function _prepareLayout() { $infoBlockAlias = $this->_getInfoBlockClassAlias(); if (null !== $infoBlockAlias) { $this->insert($this->_createChildBlock($infoBlockAlias)); } } private function _getInfoBlockClassAlias() { switch ($this->getAttributeSetId()) { case $this->kitchenAttributeSetId: return 'example_attributesetinfo/info_kitchen'; case $this->chairAttributeSetId: return 'example_attributesetinfo/info_chair'; case $this->insuranceAttributeSetId: return 'example_attributesetinfo/info_insurance'; } } 56 The beautiful Magento Module November, 1st 2014
  • 57. The attribute set dependent differences are encapsulated class Example_AttributeSetInfo_Block_Info_Chair extends Mage_Core_Block_Template { protected function _prepareLayout() { $this->setTemplate('example/attributesetinfo/chair-info.phtml'); } public function getChairCoverWashingInstructionsPDFUrl() { return 'the url of the chair cover washing instructions pdf'; } } 57 The beautiful Magento Module November, 1st 2014
  • 58. Encapsulate what varies What would be affected by change? What would be affected by adding an attribute set? What would be affected if the output for one attribute set needs to change? 58 The beautiful Magento Module November, 1st 2014
  • 59. More Principles 59 The beautiful Magento Module November, 1st 2014
  • 60. What else makes a module beautiful? 60 The beautiful Magento Module November, 1st 2014
  • 61. Readable Code 61 The beautiful Magento Module November, 1st 2014
  • 62. Readable Code What makes code readable? Coding Standard 62 The beautiful Magento Module November, 1st 2014
  • 63. Obviously private function getInfoBlockClassAliasBadExample () { if ($this->getAttributeSetId()==$this->kitchenAttributeSetId) return 'example_attributesetinfo/info_kitchen'; if($this->chairAttributeSetId == $this->getAttributeSetId()) return 'example_attributesetinfo/info_chair'; else // insurance attribute set return 'example_attributesetinfo/info_insurance'; } private function getInfoBlockClassAliasGoodExample() { switch ($this->getAttributeSetId()) { case $this->kitchenAttributeSetId: return 'example_attributesetinfo/info_kitchen'; case $this->chairAttributeSetId: return 'example_attributesetinfo/info_chair'; case $this->insuranceAttributeSetId: return 'example_attributesetinfo/info_insurance'; } } 63 The beautiful Magento Module November, 1st 2014
  • 64. Readable Code What else makes code readable? Descriptive method names 64 The beautiful Magento Module November, 1st 2014
  • 65. Readable Code How can we choose good method names? A method should do only one thing. The name should state that thing. 65 The beautiful Magento Module November, 1st 2014
  • 66. Readable Code If naming a method is hard split it into smaller ones. 66 The beautiful Magento Module November, 1st 2014
  • 67. Readable Code First some examples of method names that could be improved 67 The beautiful Magento Module November, 1st 2014
  • 68. One bad example straight out of the Magento ORM protected function _construct() { $this->_init('example_module/foo'); } 68 The beautiful Magento Module November, 1st 2014
  • 69. I find this would be nicer to read protected function _initializeCollection() { $this->_setModelClassAlias('example_module/foo'); } 69 The beautiful Magento Module November, 1st 2014
  • 70. Readable Code Methods returning a boolean value should start with is or has public function isNewObject() {...} public function hasChildren() {...} 70 The beautiful Magento Module November, 1st 2014
  • 71. Readable Code Setters should start with set $request->setDispatched(false) 71 The beautiful Magento Module November, 1st 2014
  • 72. Readable Code Some more good bad examples 72 The beautiful Magento Module November, 1st 2014
  • 73. Similar methods need very descriptive names to be self documenting // from Mage_Catalog_Model_Category public function getChildrenCategories() {...} public function getChildrenCategoriesWithInactive() {...} public function getChildren() {...} public function getAllChildren(...) {...} public function getCategories(...) {...} 73 The beautiful Magento Module November, 1st 2014
  • 74. Dead code should be removed without mercy // from Mage_Core_Model_Email public function __construct() { // TODO: move to config $this->setFromName('Magento'); $this->setFromEmail('magento@varien.com'); $this->setType('text'); } 74 The beautiful Magento Module November, 1st 2014
  • 75. WTF // from Mage_Shipping_Model_Carrier_Abstract public function getTotalNumOfBoxes($weight) { // ... return $weight; } 75 The beautiful Magento Module November, 1st 2014
  • 76. Wrap up 76 The beautiful Magento Module November, 1st 2014
  • 77. Wrap up What qualifies a Magento module as beautiful? 1.It provides business value 2.Magento can be upgraded without breaking the module 3.It is easy to understand and modify 4.It has good test coverage 5.It is free of bugs 77 The beautiful Magento Module November, 1st 2014
  • 78. Further reading 78 The beautiful Magento Module November, 1st 2014
  • 79. Further reading Link to Amazon 79 The beautiful Magento Module November, 1st 2014
  • 80. Further reading Link to Amazon 80 The beautiful Magento Module November, 1st 2014
  • 81. Further reading Link to Amazon 81 The beautiful Magento Module November, 1st 2014
  • 82. Further reading Link to Amazon 82 The beautiful Magento Module November, 1st 2014
  • 83. Thank you 83 The beautiful Magento Module November, 1st 2014
  • 84. Questions | Comments Tweet me @VinaiKopp http://vinaikopp.com 84 The beautiful Magento Module November, 1st 2014

Hinweis der Redaktion

  1. My name is Vinai Kopp, thanks for being here.
  2. I think it is important to understand as much as possible about Magento 1, as it is the basis for Magento 2, where the framework has received a massive overhaul, but is still based on the same architectural ideas as Magento 1 is.
  3. In fact, I think Magento 1 contributed a lot of education to the PHP community in its time. And still it can be used as a great example, for both: good and bad design. The trouble is figuring out which is which :-)
  4. There are many excellent resources available blogs, IRC, books and videos and classroom trainings as they are offered, amongst others, by Magento U. If you are new to the Magento framework, I hope this talk will be able to give a little context that might be useful should you decide to learn more. If you already have a couple of projects or more under your belt, this talk will hopefully facilitate you in gaining a deeper understanding of Magento 1.
  5. I like the poetic connotations of the term “beautiful”. It inspires me to try to think outside of my box. If you feel uncomfortable with the word “beautiful” please feel free to think “clean” instead.
  6. A module that shows all these qualities is a thing of beauty. This presentation is about how I try to achieve this goals, and what I learned along the way.
  7. I stumbled over design patterns and principles of object oriented development while working with Magento. It took me a while to read up about these things, but I have been intrigued ever since. It's genius!
  8. Many of these first principles of object oriented development where formulated by Robert C. Martin, a.k.a. Uncle Bob. He has provided me with great inspiration!
  9. There are more principles, and sometimes they are known with different names. By applying principles patterns are discovered. * SRP A class should have only one reason to change. Encapsulate what varies. * OCP Classes should be open for extension but closed for modification. * ISP Program to interfaces, not implementations. Depend upon abstractions. Do not depend upon concrete classes.
  10. We'll discuss how a couple of these principles can be applied in custom Magento modules, and also have a look at concrete code examples in the Magento core.
  11. Applying these principles supports a developer to create a well designed piece of software. This is true for full applications, but also for Magento modules, though maybe on a smaller scale.
  12. All principles should only be applied with care in areas where they make sense. Disclaimer: if you try to apply them all the time, it will lead to over engineered and too complex code. The first principle I would like to talk about is
  13. The Open Closed Principle
  14. According to this principle, new functionality should be created by writing new code, not by modifying existing code.
  15. Yes it has :)
  16. Node values are overwritten during config XML merging. That is the basic idea of many ways Magento is open for extension. It is Magento's implementation of the Plugin Pattern as recorded by Martin Fowler. In practice it definitely has its uses, but in the long run customizations based on configuration value overwriting (and that includes rewrites) often lead to conflicts.
  17. I believe an important part of the Open Closed Principle is that a piece of software should tell the outside world how to extended it.
  18. For example, on a class level this is where method visibility comes into play. Visibility and method naming is how classes can be made self documenting.
  19. Public methods are like an open invitation to the world to use them.
  20. Once we declare a public method and publish the class, that method signature can never again be changed without risking external code calling the method to be broken. Introducing new side effects to a public method that weren't there before is also quite risky.
  21. So what about the internal visibilities, protected and private? Each of those has a specific purpose, too.
  22. This protected method signature is now frozen. Again, any signature or functionality change might break subclasses!
  23. Private visibility is for the class itself only. If it requires a change down the road, no problem. As long as the public and protected interfaces stay the same, there is no problem.
  24. One reason for large technical debt. Any change has to be awkwardly engineered around the existing interfaces. At first glance it seems like a great thing to be able to override any method, but in hindsight it probably was a bad design choice. Many implementation details should have been hidden within private scope visibility. Exposing a method as public or protected should only be done with good reason.
  25. This is a great example how method visibility can tell developers how a class should be extended. By the way, this is an example of the Template Method pattern's hook operations.
  26. My favorite way to customize Magento. As we all know, following best practices it is possible to create customizations that are less conflict prone, without needing to change any existing code. It is no coincidence that the Event Observer pattern is so wide spread and well known. Probably this is one of the patterns most developers start using without ever having studied patterns.
  27. How can we follow the Open Closed Principle within custom modules? By dispatching custom events
  28. Choose events that describe the business logic of your module.
  29. Think of events in terms of Domain Events, for example this_will_happen or this_just_happened rather then Instructions as do_this_now.
  30. Of course you need to make the external interface public. But every internal method should be private by default. Only if you really want to use the Template Method pattern or need to encapsulate variations in a subclass, then make a method protected. We'd better expose methods as protected only if we want invite other developers to change the implementation of that method. On that note, when declaring a method as protected, make sure you do not call any other methods of the abstract class from within the method. A subclass should never call methods of its superclass (the Hollywood Principle).
  31. Even if it has its downsides, class rewrites have their place within the Magento framework.
  32. Using a factory method with a PHP class name is no better then instantiating a class directly using the new operator.
  33. Memorizing the class name resolution process is one of the most beneficial things to improve our effectiveness as a Magento developer.
  34. By using class aliases we can keep our module open for extension. By choosing the correct method visibility we can define how we want our code to be extendable.
  35. The next principle is "encapsulate what varies" This is one of my favorite principles. It closely related to the Single Responsibility principle (SRP)
  36. This pattern was defined by Davod Parnas and popularized by the GoF Design Patterns book. It is the basis of the Strategy Pattern. Applying this principle leads to a design with a relatively large number of small classes. Like all principles, this one also is to help us deal with the changes that occur within software over time.
  37. Like all principles, this one also is to help us deal with the changes that occur within software over time. It's impossible to anticipate everything that will change or vary over the lifetime of a project, but often things will need to be different depending on circumstances already becomes apparent during development.
  38. So what are examples of this principle in the Magento core?
  39. Maybe it is easier to understand how it looks like when the principle is not adhered to. Lets see in what kind of situations this principle should be applied.
  40. A bit of background: in Magento different tax calculation algorithms can be configured. Instead of delegating to a separate class depending on the tax calculation settings, each algorithm is implemented within one class, The tax total model
  41. This actually doesn't look that bad. The problem is however, that any change to one of the algorithms, even a small bugfix, can have an impact on the others, too. Each calculation could have been encapsulated within one class. That would probably be a more robust design. A smaller class is also easier to read. This is an especially important aspect for complex things like tax calculation.
  42. The behavior of the order often depends on the order state. There are many methods to check which actions are possible for an order depending on its current state.
  43. There are many more similar methods, e.g. canInvoice(), canCreditmemo(), canReorder(). I find the method pretty hard to understand. Imagine a change to one of these methods that are called. It might affect the behavior other states because of the interdependencies.
  44. That is nice descriptive code! Encapsulating behavior into different state dependent classes would make things much easier to understand and maintain. That is so common that it has its own pattern: the State Pattern (GoF).
  45. Instead of having the complete total calculation within one class, it is encapsulated in a list of delegates. The extensibility this brings has already been used by the core team when implementing the tax total model, which didn't effect for example the shipping total model at all.
  46. One of my favorite parts of Magento's EAV design is the ability to encapsulate business logic on an attribute level using backend and source models. A custom index needs to be updated after a value changes? No problem, a backend model to the rescue. An attribute needs to be populated with an entity ID from a collection? Hey, we can use a source model for that. So good :)
  47. Lets have a look at how we can apply encapsulate what varies in our own code.
  48. How about a simple but concrete example. Lets assume we want to enrich the product detail page with information depending on a products attribute set. We want to add a new block as a child of the `product.info.media.after` block.
  49. For the examples sake lets assume we have the attribute sets "Kitchen", "Chair", and "Insurance". You might imagine that each of those needs to display quite different information.
  50. The method chooses a template depending on the current products attribute set.
  51. In addition to choosing the template, the block would also have to provide all the methods called within the different attribute set dependent templates, although each concrete template only needs a subset of those. Not so nice. So, how can we apply the ECV principle to clean things up?
  52. We need to encapsulate what varies. Basically, we want a different block for each attribute set. This leads us to the following classes. We want one block per attribute set. We also need one class to decide which attribute set block to use a Block Locator.
  53. In order to keep things within the Magento framework, lets make the locator a kind of proxy for the info blocks. This is easiest accomplished by using a `core/text_list` block, which - as you probably know - automatically renders all its child blocks. The child block will then be the specific attribute info block instance.
  54. This is how an implementation of the Locator could look like. How is this better then the previous example? We still have a switch statement. The difference is this time this is the ONLY responsibility of this class. The rendering of the specific attribute set dependent information is encapsulated within the child block.
  55. In this example the specific child block sets its appropriate template and provide all the required methods for one attribute set.
  56. If a new attribute set is added, only the Locator class needs to be changed. If the rendered information for one of the attribute sets needs to change, none of the other attribute sets are affected. This makes our code more resilient against change.
  57. All the principles help us developers to create more well designed software. Unfortunately they are outside of the scope of this presentation because of time constraints. However, if you are not familiar with them, I do encourage you to invest time studying them, and also design patterns.
  58. What else besides Principles and Patterns makes a module beautiful?
  59. Whenever we need to inspect a module we have to read code and understand what it does. It is a fact that we all spend more time reading code then writing code.
  60. It doesn't matter if it is the coding standard Magento uses is the best one out there or if matches is your personal preference. Use it. Probably you know this experience... getting some code to review and first having to spend 15 minutes reformatting every file to match the coding standard. Its easy - all IDEs and most editors allow you to reformat a complete file with a few key strokes.
  61. If I have to review code that doesn't match the standard, my first impression of that developer is that he probably is a stubborn n00b. What it comes down to is that indention, placements of brackets, whitespace and casing is all consistent. There are still so many other things we can decide ourselves how they should be.
  62. If it is hard to choose a name for a method, that probably means it does to much and should be split into several smaller methods.
  63. Looks familiar? What happens during `_init`? What is the string `example_module/foo`? The code doesn't tell us. How could it be better?
  64. Oh, this isn't a model, its a collection we are looking at. :)
  65. Lets say the method names probably could be more descriptive... What is the difference between all these methods? Do they return the same or different types? The method names don't help us.
  66. TODO since 6+ years... ;)
  67. And this is just mean
  68. This is not an ideal. It is a realistic goal, and quite achievable. Focus on solving real business problems. Study the principles and patterns, Write readable code. Write tests.
  69. The following are some of the best books on development I know. They have inspired me a lot. If you don't know them already and you want to become a better developer, study them.
  70. Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin http://amzn.com/0132350882
  71. Design Patterns - Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides http://amzn.com/0201633612
  72. Head First Design Patterns by Eric and Elisabeth Freeman with Kerry Sierra and Bert Bates http://amzn.com/0596007124
  73. Softwarequalität in PHP Projekten, 2. Edition (German) by Sebastian Bergman and Stefan Priebsch http://www.amazon.de/dp/3446435395
  74. Jon Woodall & the others from MageTitans for inviting me! Standing on the sholders of giants: Thank you to Robert C. Martin, Martin Fowler, Kent Beck, Stefan Priebsch and all the others who have taught me so much about software. Thank you to the Magento Community - inspiration, learning opportunities and friendship galore! And thanks to Magento, too, for providing us with this playing field! Without you all of us would not be here. And finally thank you all for listening!